#include "ClientGame.h"
#include "GraphicsDeviceManager.h"
#include "WindowManager.h"
#include "KeyboardManager.h"
#include "MouseManager.h"
#include "CameraManager.h"
#include "ActorManager.h"
#include "QuakeCamera.h"
#include "OrbitCamera.h"
#include "TextureManager.h"
#include "MatrixHelper.h"
#include "BoundingBox.h"
#include "Common.h"
#include "MatrixHelper.h"
#include "BoundingBoxRenderer.h"
#include "BoundingSphereRenderer.h"

ClientGame::ClientGame()
{
}
	
ClientGame::~ClientGame()
{
	delete m_pBsp;
}

ClientGame* ClientGame::GetInstance()
{
	return m_pInstance;
}

void ClientGame::LoadContent()
{
	Game::LoadContent();

	m_pBsp = new Bsp();
	
	m_pBsp->Load("Content/Maps/Reassimilation.bsp");
}

void ClientGame::Initialize()
{
	Game::Initialize();

	QuakeCamera* quakeCamera = new QuakeCamera();

	GetCameraManager()->Add(quakeCamera);
	GetCameraManager()->SetCurrentCamera(quakeCamera);

	MouseManager::GetInstance()->SetVisible(false);
}

void ClientGame::Update(float elapsedTime)
{
	if(KeyboardManager::GetInstance()->IsKeyPressed(GLFW_KEY_ESC))
	{
		Exit();
	}

	if(MouseManager::GetInstance()->IsButtonDown(MOUSEBUTTON_LEFT))
	{
		Camera* pCamera = GetCameraManager()->GetCurrentCamera();
		Vector3f vBegin = pCamera->GetPosition();
		Vector3f vForward;
		Vector3f vEnd;

		Matrix matrix;
		MatrixHelper::LoadIdentity(matrix);
		MatrixHelper::SetRotation(matrix, pCamera->GetAbsoluteRotation());
		MatrixHelper::GetForward(matrix, vForward);

		vEnd = vBegin + (vForward * 64.0f);

		m_vTraceLocation = m_pBsp->TraceRay(vBegin, vEnd);
	}

	Game::Update(elapsedTime);
}

void ClientGame::Draw()
{
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	m_pBsp->Draw();

	BoundingSphereRenderer::Draw(BoundingSphere(m_vTraceLocation, 4.0f));

	Game::Draw();
}

void ClientGame::UnloadContent()
{
	Game::UnloadContent();
}

void ClientGame::Run()
{
	float previousElapsedTime = 0.0f;

	float currentElapsedTime = GetElapsedTime();

	float elapsedTime = 0.0f;

	while(WindowManager::IsOpen() && !IsExiting())
	{
		previousElapsedTime = currentElapsedTime;

		currentElapsedTime = GetElapsedTime();

		elapsedTime = currentElapsedTime - previousElapsedTime;

		Update(elapsedTime);

		Sleep(4);

		Draw();
	}
}

ClientGame* ClientGame::m_pInstance = new ClientGame();